package com.eliza.kotlin.design.creation.single

import com.eliza.ktor.all.library.utils.ToolsLog
import java.io.*


/*-*- coding:utf-8 -*-
 * @Author  : debi
 * @Time    : 6/4/22
 * @Software: IntelliJ IDEA
 */

/**
 * 破坏单例模式：
 * （Singleton）可以创建多个对象，枚举方式除外。有两种方式，分别是序列化和反射
 */
class BreakSingleton : Serializable {
    private constructor()

    companion object {
        object SingletonHolder {
            val INSTANCE = BreakSingleton()
        }

        fun getInstance() = SingletonHolder.INSTANCE

    }
    //当进行反序列化时，会自动调用该方法，将该方法的返回值直接返回
    /**
     * 下面是为了解决序列化反序列化破解单例模式
     */
    fun readResolve(): Any = SingletonHolder.INSTANCE

}

/**
 * Read object from file
 * 从文件读取数据（对象）
 * @param path
 */
fun readObjectFromFile(path: String): BreakSingleton {
    //1,创建对象输入流对象
    val ois = ObjectInputStream(FileInputStream(path))
    //2,读取对象
    val instance = ois.readObject() as BreakSingleton
    //释放资源
    ois.close()
    return instance
}

/**
 * Write object2file
 *     //向文件中写数据（对象）

 * @param path
 */
fun writeObject2File(path: String, instance: BreakSingleton) {
    //1,获取Singleton对象
//    val instance = Singleton2.getInstance()
    //2,创建对象输出流对象
    val oos = ObjectOutputStream(FileOutputStream(path))
    //3,写对象
    oos.writeObject(instance)
    //4,释放资源
    oos.close()
}

fun main() {
    var path = "/home/debi/IdeaProjects/Kotlin/design/src/main/resources/design/creation/single/single.txt"

    val instance = BreakSingleton.getInstance()
    writeObject2File(path, instance)

    ToolsLog.LogPrintln(" ${instance.hashCode()}\n ${readObjectFromFile(path).hashCode()}", 4)

    ToolsLog.LogPrintln(instance == readObjectFromFile(path), 13)
}